home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / flow.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  22KB  |  527 lines

  1. /*  $VER: vbcc (flow.c) V0.4     */
  2. /*  Generierung des FLussgraphs und Optimierungen des Kontrollflusses   */
  3.  
  4. #include "opt.h"
  5.  
  6. static char FILE_[]=__FILE__;
  7.  
  8. int bvcmp(unsigned char *dest,unsigned char *src,size_t len)
  9. /*  vergleicht zwei Bitvektoren    */
  10. {
  11.     for(;len>0;len--)
  12.         if(*dest++!=*src++) return(0);
  13.     return(1);
  14. }
  15. void bvunite(unsigned char *dest,unsigned char *src,size_t len)
  16. /*  berechnet Vereinigung zweier Bitvektoren    */
  17. {
  18.     for(;len>0;len--)
  19.         *dest++|=*src++;
  20. }
  21. void bvintersect(unsigned char *dest,unsigned char *src,size_t len)
  22. /*  berechnet Durchschnitt zweier Bitvektoren   */
  23. {
  24.     for(;len>0;len--)
  25.         *dest++&=*src++;
  26. }
  27. void bvdiff(unsigned char *dest,unsigned char *src,size_t len)
  28. /*  berechnet 'Differenz' zweier Bitvektoren    */
  29. {
  30.     for(;len>0;len--)
  31.         *dest++&=~(*src++);
  32. }
  33.  
  34. unsigned int basic_blocks;
  35.  
  36. struct flowgraph *construct_flowgraph(void)
  37. /*  entfernt ueberfluessige Labels und erzeugt Flussgraph   */
  38. {
  39.     struct IC *p;
  40.     int firstl=lastlabel,lcnt=label-firstl,currentl,i,code,l;
  41.     int *iseq=mymalloc(lcnt*sizeof(int));
  42.     int *used=mymalloc(lcnt*sizeof(int));
  43.     struct flowgraph **lg=mymalloc(lcnt*sizeof(struct flowgraph *));
  44.     struct flowgraph *g=mymalloc(sizeof(struct flowgraph)),*fg=g;
  45.     g->start=first_ic;g->in=0;g->branchout=0;g->loopend=0;
  46.  
  47.     for(i=0;i<lcnt;i++) {iseq[i]=used[i]=0;lg[i]=0;}
  48.     currentl=0;firstl++;
  49.     /*  Diese Schleife entfernt alle Labels, die mit anderen    */
  50.     /*  uebereinstimmen, merkt sich das und kennzeichnet alle   */
  51.     /*  Labels, die benutzt werden.                             */
  52.     /*  Ausserdem wird der Flussgraph teilweise aufgebaut.      */
  53.     if(DEBUG&1024) {puts("construct_flowgraph(): loop1");/*scanf("%d",&i);*/}
  54.     i=1;g->index=i;
  55.     for(p=first_ic;p;){
  56.         code=p->code;
  57.         if(code>=BEQ&&code<=BRA){
  58.             l=p->typf;
  59.             /*  als used markieren; falls aequivalent, das erste markieren  */
  60.             if(iseq[l-firstl]) used[iseq[l-firstl]-firstl]=1;
  61.                 else           used[l-firstl]=1;
  62.             /*  Flussgraph beenden und evtl. naechsten Knoten erzeugen  */
  63.             g->end=p;
  64.             if(p->next){
  65.                 g->normalout=mymalloc(sizeof(struct flowgraph));
  66.                 g->normalout->in=mymalloc(sizeof(struct flowlist));
  67.                 g->normalout->in->next=0;
  68.                 g->normalout->in->graph=g;
  69.                 g=g->normalout;
  70.                 g->start=p->next;
  71.                 g->branchout=0;
  72.                 g->loopend=0;
  73.                 g->index=++i;
  74.             }else g->normalout=0;
  75.  
  76.             currentl=0;p=p->next;continue;
  77.         }
  78.         if(code==ALLOCREG||code==FREEREG){p=p->next; continue;}
  79.         if(code!=LABEL){currentl=0;p=p->next;continue;}
  80.         /*  ist ein Label   */
  81.         l=p->typf;
  82.         if(currentl){
  83.         struct IC *m;
  84.             iseq[l-firstl]=currentl;
  85.             if(used[l-firstl]) used[currentl-firstl]=1;
  86.         m=p;p=p->next;
  87.             remove_IC(m);
  88.         continue;
  89. /*            if(DEBUG&1024) printf("label %d==%d\n",l,iseq[l-firstl]);*/
  90.         }else{
  91.             currentl=l;
  92.             if(g->start!=p){
  93.                 g->end=p->prev;
  94.                 g->normalout=mymalloc(sizeof(struct flowgraph));
  95.                 g->normalout->in=mymalloc(sizeof(struct flowlist));
  96.                 g->normalout->in->next=0;
  97.                 g->normalout->in->graph=g;
  98.                 g=g->normalout;
  99.                 g->start=p;
  100.                 g->branchout=0;
  101.                 g->loopend=0;
  102.                 g->index=++i;
  103.             }else g->branchout=0;
  104.             lg[l-firstl]=g;
  105.         }
  106.     p=p->next;
  107.     }
  108.     g->end=last_ic;g->normalout=g->branchout=0;
  109.     if(DEBUG&1024) printf("%d basic blocks\n",i);
  110.     basic_blocks=i;
  111.  
  112. /*    if(DEBUG&1024) for(i=firstl;i<=lcnt;i++) printf("L%d used: %d\n",i,used[i-firstl]);*/
  113.     /*  Diese Schleife entfernt alle nicht benutzten Labels und biegt alle  */
  114.     /*  Branches auf aequivalente Labels um.                                */
  115.     if(DEBUG&1024) {puts("construct_flowgraph(): loop2");/*scanf("%d",&i);*/}
  116.     g=fg;
  117.     while(g){
  118.         int flag=0;struct flowlist *lp;
  119. /*        printf("g=%p\n",(void *)g);*/
  120.         g->av_in=g->av_out=g->av_gen=g->av_kill=0;
  121.         g->rd_in=g->rd_out=g->rd_gen=g->rd_kill=0;
  122.         g->ae_in=g->ae_out=g->ae_gen=g->ae_kill=0;
  123.         g->cp_in=g->cp_out=g->cp_gen=g->cp_kill=0;
  124.         p=g->start;
  125.         while(p&&!flag){
  126. /*            pric2(stdout,p);*/
  127.             code=p->code;
  128.             if(code>=BEQ&&code<=BRA){
  129.                 l=p->typf;
  130.                 if(iseq[l-firstl]) p->typf=l=iseq[l-firstl];
  131.                 /*  in Flussgraph eintragen */
  132.                 g->branchout=lg[l-firstl];
  133.                 if(!lg[l-firstl]) ierror(0);
  134.                 lp=lg[l-firstl]->in;
  135.                 /*  das hier sollte man noch schoener machen    */
  136.                 if(!lp){
  137.                     lg[l-firstl]->in=mymalloc(sizeof(struct flowlist));
  138.                     lg[l-firstl]->in->next=0;
  139.                     lg[l-firstl]->in->graph=g;
  140.                 }else{
  141.                     while(lp&&lp->next) lp=lp->next;
  142.                     lp->next=mymalloc(sizeof(struct flowlist));
  143.                     lp->next->next=0;
  144.                     lp->next->graph=g;
  145.                 }
  146.             }
  147. /*            if(code==LABEL&&!used[p->typf-firstl]) remove_IC(p);*/
  148.             if(p==g->end) flag=1;
  149.             p=p->next;
  150.         }
  151.         g=g->normalout;
  152.     }
  153.     /*  Unbenutzte Labels entfernen und Bloecke verbinden   */
  154.     if(DEBUG&1024) {puts("construct_flowgraph(): loop3");/*scanf("%d",&i);*/}
  155.     for(g=fg;g;g=g->normalout){
  156.         if(g->end&&(g->end->code<BEQ||g->end->code>BRA)){
  157.             struct flowgraph *next=g->normalout;struct flowlist *lp;
  158.             if(next&&next->start&&next->start->code==LABEL&&!used[next->start->typf-firstl]){
  159.                 if(next->end!=next->start) g->end=next->end;
  160.                 g->normalout=next->normalout;
  161.                 g->branchout=next->branchout;
  162.                 free(next->in); /*  darf eigentlich nur einen Vorgaenger haben  */
  163.                 /*  in im Nachfolgeknoten auf den ersten der beiden setzen  */
  164.                 if(next->normalout&&next->normalout->in) next->normalout->in->graph=g;
  165.                 /*  in im Ziel von next->branchout auf den ersten setzen    */
  166.                 if(next->branchout){
  167.                     lp=next->branchout->in;
  168.                     while(1){
  169.                         if(lp->graph==next){ lp->graph=g;break;}
  170.                         lp=lp->next;if(!lp) ierror(0);
  171.                     }
  172.                 }
  173.                 if(DEBUG&1024){ printf("unused label deleted:\n");pric2(stdout,next->start);}
  174.                 remove_IC(next->start);
  175.                 free(next);
  176.             }
  177.         }
  178.         /*  unbenutzte Labels entfernen */
  179.         if(g->start&&g->start->code==LABEL&&!used[g->start->typf-firstl])
  180.             remove_IC_fg(g,g->start);
  181.     }
  182.     free(iseq);
  183.     free(used);
  184.     return(fg);
  185. }
  186.  
  187. void print_flowgraph(struct flowgraph *g)
  188. /*  Gibt Flussgraph auf Bildschirm aus  */
  189. {
  190.     static int dontprint=0;
  191.     int flag,i;struct flowlist *lp;struct IC *ip;
  192.     if(dontprint) {dontprint--;return;}
  193.     puts("print_flowgraph()");scanf("%d",&i);
  194.     if(i<0){dontprint=-i;return;}
  195.     if(!i) return;
  196.     while(g){
  197.         printf("\nBasic Block nr. %d\n",g->index);
  198.         printf("\tin from ");
  199.         lp=g->in;
  200.         while(lp){if(lp->graph) printf("%d ",lp->graph->index);lp=lp->next;}
  201.         printf("\n\tout to %d %d\n",g->normalout?g->normalout->index:0,g->branchout?g->branchout->index:0);
  202.         if(g->loopend) printf("head of a loop ending at block %d\n",g->loopend->index);
  203.         if(i&2){
  204.             printf("av_gen:\n"); print_av(g->av_gen);
  205.             printf("av_kill:\n"); print_av(g->av_kill);
  206.             printf("av_in:\n"); print_av(g->av_in);
  207.             printf("av_out:\n"); print_av(g->av_out);
  208.         }
  209.         if(i&4){
  210.             printf("rd_gen:\n"); print_rd(g->rd_gen);
  211.             printf("rd_kill:\n"); print_rd(g->rd_kill);
  212.             printf("rd_in:\n"); print_rd(g->rd_in);
  213.             printf("rd_out:\n"); print_rd(g->rd_out);
  214.         }
  215.         if(i&8){
  216.             printf("ae_gen:\n"); print_ae(g->ae_gen);
  217.             printf("ae_kill:\n"); print_ae(g->ae_kill);
  218.             printf("ae_in:\n"); print_ae(g->ae_in);
  219.             printf("ae_out:\n"); print_ae(g->ae_out);
  220.         }
  221.         if(i&16){
  222.             printf("cp_gen:\n"); print_cp(g->cp_gen);
  223.             printf("cp_kill:\n"); print_cp(g->cp_kill);
  224.             printf("cp_in:\n"); print_cp(g->cp_in);
  225.             printf("cp_out:\n"); print_cp(g->cp_out);
  226.         }
  227.         if(i&32){
  228.             int r;
  229.             for(r=1;r<=MAXR;r++)
  230.                 if(g->regv[r]) printf("(%s),%ld assigned to %s\n",g->regv[r]->identifier,(long)zl2l(g->regv[r]->offset),regnames[r]);
  231.         }
  232.         flag=0;ip=g->start;
  233.         while(ip&&!flag){
  234.             pric2(stdout,ip);
  235.             if(i&64){
  236.                 int r;
  237.                 printf("changes: ");
  238.                 for(r=0;r<ip->change_cnt;r++)
  239.                     printf("(%s,%ld,%d,%d)",ip->change_list[r].v->identifier,(long)zl2l(ip->change_list[r].v->offset),ip->change_list[r].flags,ip->change_list[r].v->index);
  240.                 printf("\nuses: ");
  241.                 for(r=0;r<ip->use_cnt;r++)
  242.                     printf("(%s,%ld,%d,%d)",ip->use_list[r].v->identifier,(long)zl2l(ip->use_list[r].v->offset),ip->use_list[r].flags,ip->use_list[r].v->index);
  243.                 printf("\n");
  244.             }
  245.             if(ip==g->end) flag=1;
  246.             ip=ip->next;
  247.         }
  248.         g=g->normalout;
  249.     }
  250. }
  251. void free_flowgraph(struct flowgraph *g)
  252. /*  Gibt Flussgraph frei    */
  253. {
  254.     struct flowgraph *pm;struct flowlist *lp,*lpm;
  255.     if(DEBUG&1024) puts("free_flowgraph()");
  256.     while(g){
  257.         lp=g->in;
  258.         while(lp){
  259.             lpm=lp->next;
  260.             free(lp);
  261.             lp=lpm;
  262.         }
  263.         free(g->av_in);
  264.         free(g->av_out);
  265.         free(g->av_gen);
  266.         free(g->av_kill);
  267.         free(g->rd_in);
  268.         free(g->rd_out);
  269.         free(g->rd_gen);
  270.         free(g->rd_kill);
  271.         free(g->ae_in);
  272.         free(g->ae_out);
  273.         free(g->ae_gen);
  274.         free(g->ae_kill);
  275.         free(g->cp_in);
  276.         free(g->cp_out);
  277.         free(g->cp_gen);
  278.         free(g->cp_kill);
  279.  
  280.         pm=g->normalout;
  281.         free(g);
  282.         g=pm;
  283.     }
  284. }
  285. struct flowgraph *jump_optimization(void)
  286. /*  entfernt ueberfluessige Spruenge etc.                           */
  287. {
  288.     struct flowgraph *fg,*g;struct IC *p;int changed,i;
  289.     struct flowlist *lp;
  290.     do{
  291.         changed=0;
  292.         fg=construct_flowgraph();
  293.         if(DEBUG&1024) {printf("jump_optimization() pass\n");print_flowgraph(fg);}
  294.         g=fg;
  295.         while(g){
  296.             /*  tote Bloecke entfernen                  */
  297.             if(g!=fg) i=0; else i=1;    /*  erster Block nie tot    */
  298.             lp=g->in;
  299.             while(!i&&lp){
  300.                 struct flowgraph *t=lp->graph;
  301.                 if(t){
  302.                     if((t!=g&&t->branchout==g)||!t->end||(t!=g&&t->end->code!=BRA)) i=1;
  303.                 }
  304.                 lp=lp->next;
  305.             }
  306.             if(!i){
  307.                 struct IC *m;
  308.                 if(DEBUG&1024) printf("deleting dead block %d\n",g->index);
  309.                 p=g->start;
  310.                 while(p&&!i){
  311.                     if(p==g->end) i=1;
  312.                     if(DEBUG&1024) pric2(stdout,p);
  313.                     m=p->next;
  314.                     remove_IC_fg(g,p);changed=gchanged=1;
  315.                     p=m;
  316.                 }
  317.                 if(g->branchout){
  318.                 /*  Eintrag in Ziel loeschen (nur einmal, falls auch normalout)    */
  319.                     lp=g->branchout->in;
  320.                     while(lp){
  321.                         if(lp->graph==g){ lp->graph=0;break;}
  322.                         lp=lp->next;
  323.                     }
  324.                     g->branchout=0;
  325.                 }
  326.                 g=g->normalout;continue;
  327.             }
  328.             /*  Spruenge zum folgenden Code entfernen   */
  329.             if(g->normalout&&g->normalout==g->branchout){
  330.                 p=g->end;
  331.                 if(!p||p->code<BEQ||p->code>BRA) ierror(0);
  332.                 if(DEBUG&1024){printf("branch to following label deleted:\n");pric2(stdout,p);}
  333.                 remove_IC_fg(g,p);g->branchout=0;changed=gchanged=1;
  334.                 p=g->end;
  335.                 /*  vorangehenden Vergleich auch entfernen  */
  336.                 if(p&&(p->code==COMPARE||p->code==TEST)){
  337.                     if(DEBUG&1024){printf("preceding comparison also deleted:\n");pric2(stdout,p);}
  338.                     remove_IC_fg(g,p);
  339.                 }
  340.             }
  341.             /*  Spruenge zu Spruengen umsetzen; einige Zeiger im Flussgraph */
  342.             /*  werden nicht korrekt aktualisiert, aber das sollte egal sein*/
  343.             p=g->start;
  344.             for(i=0;i<2;i++){
  345.                 if(i){if(p&&p->code==LABEL) p=p->next; else break;}
  346.                 if(p&&p->code>=BEQ&&p->code<=BRA){
  347.                     lp=g->in;
  348.                     while(lp){
  349.                         if(lp->graph&&lp->graph->branchout==g&&(/*lp->graph->end->code==p->code||*/p->code==BRA)&&lp->graph->end->typf!=p->typf){
  350.                             if(DEBUG&1024){printf("branch bypassed to L%d:\n",p->typf);pric2(stdout,lp->graph->end);}
  351.                             if(lp->graph->end->code<BEQ||lp->graph->end->code>BRA) ierror(0);
  352.                             lp->graph->branchout=g->branchout;
  353.                             lp->graph->end->typf=p->typf;changed=gchanged=1;
  354.                         }
  355.                         lp=lp->next;
  356.                     }
  357.                 }
  358.             }
  359.             /*  bcc l1;bra l2;l1 aendern    */
  360.             p=g->end;
  361.             if(p&&p->code>=BEQ&&p->code<BRA&&g->normalout){
  362.                 if(g->normalout->start&&g->normalout->start->code==BRA){
  363.                     if(g->normalout->normalout==g->branchout){
  364.                         g->branchout=g->normalout->branchout;
  365.                         i=p->typf;
  366.                         p->typf=g->normalout->start->typf;
  367.                         if(DEBUG&1024) printf("changing bcc l%d;bra l%d;l%d to b!cc l%d\n",i,p->typf,i,p->typf);
  368.                         switch(p->code){
  369.                         case BEQ: p->code=BNE;break;
  370.                         case BNE: p->code=BEQ;break;
  371.                         case BLT: p->code=BGE;break;
  372.                         case BGE: p->code=BLT;break;
  373.                         case BGT: p->code=BLE;break;
  374.                         case BLE: p->code=BGT;break;
  375.                         }
  376.                         g->normalout->branchout=g->normalout->normalout;
  377.                         g->normalout->start->typf=i;
  378.                         changed=gchanged=1;
  379.                     }
  380.                 }
  381.             }
  382.             /*  Haben alle Vorgaenger eines Blocks die selbe Anweisung am   */
  383.             /*  Blockende und keinen weiteren Nachfolger, dann kann die     */
  384.             /*  Anweisung in den Nachfogerblock geschoben werden            */
  385.             i=0;p=0;
  386.             for(lp=g->in;lp;lp=lp->next){
  387.                 if(lp->graph){
  388.                     struct IC *np;
  389.                     struct flowgraph *ng=lp->graph;
  390.                     struct flowlist *l2;
  391.                     /*  doppelte Bloecke loeschen und ueberspringen */
  392.                     for(l2=g->in;l2;l2=l2->next)
  393.                         if(l2!=lp&&l2->graph==ng) break;
  394.                     if(l2){ lp->graph=0;continue;}
  395.                     np=ng->end;
  396.                     if(!np){ i=-1;break;}
  397.                     if(ng->branchout&&np->code!=BRA){i=-1;break;}
  398.                     if(np->code==BRA) np=np->prev;
  399.                     if(!np){ i=-1;break;}
  400.                     if(!p){
  401.                         i=1;
  402.                         p=np;
  403.                     }else{
  404.                         if(p->code==np->code&&p->typf==np->typf&&
  405.                            p->code!=CALL&&p->code!=GETRETURN&&p->code!=PUSH&&(p->code<TEST||p->code>COMPARE)&&
  406.                            !compare_objs(&p->q1,&np->q1,p->typf)&&
  407.                            !compare_objs(&p->q2,&np->q2,p->typf)&&
  408.                            !compare_objs(&p->z,&np->z,p->typf)){
  409.                             i++;
  410.                         }else{
  411.                             i=-1;
  412.                             break;
  413.                         }
  414.                     }
  415.                 }
  416.             }
  417.             if(i>1&&g->start){
  418.                 struct IC *new=mymalloc(ICS);
  419.                 if(DEBUG&1024){ printf("moving instruction from preceding blocks to successor:\n");pric2(stdout,p);}
  420.                 changed=gchanged=1;
  421.                 memcpy(new,p,ICS);
  422.                 new->use_cnt=new->change_cnt=0;
  423.                 new->use_list=new->change_list=0;
  424.                 if(g->start->code==LABEL){
  425.                     insert_IC_fg(g,g->start,new);
  426.                 }else{
  427.                     insert_IC_fg(g,g->start->prev,new);
  428.                 }
  429.                 for(lp=g->in;lp;lp=lp->next){
  430.                     struct flowgraph *ng=lp->graph;
  431.                     if(ng){
  432.                         if(!ng->end) ierror(0);
  433.                         if(ng->end->code==BRA){
  434.                             remove_IC_fg(ng,ng->end->prev);
  435.                         }else{
  436.                             remove_IC_fg(ng,ng->end);
  437.                         }
  438.                     }
  439.                 }
  440.             }
  441.             /*  Haben alle Nachfolger eines Blocks die selbe Anweisung am   */
  442.             /*  Blockbeginn und keinen weiteren Vorgaenger, dann kann die   */
  443.             /*  Anweisung in den Vorgaengerblock geschoben werden           */
  444.             if(g->branchout&&g->normalout&&g->branchout!=g->normalout&&g->end&&g->end->code!=BRA){
  445.                 struct flowgraph *a=g->normalout,*b=g->branchout;
  446.                 struct IC *as=a->start,*bs=b->start,*tp;
  447.                 int destroys;
  448.                 if(as&&as->code==LABEL&&as!=a->end) as=as->next;
  449.                 if(bs&&bs->code==LABEL&&bs!=b->end) bs=bs->next;
  450.  
  451.                 if(as&&bs&&as->code==bs->code&&as->code!=PUSH&&(as->code<TEST||as->code>COMPARE)&&as->typf==bs->typf&&
  452.                    !compare_objs(&as->q1,&bs->q1,as->typf)&&
  453.                    !compare_objs(&as->q2,&bs->q2,as->typf)&&
  454.                    !compare_objs(&as->z,&bs->z,as->typf)){
  455.                     i=0;
  456.                     for(lp=a->in;lp;lp=lp->next)
  457.                         if(lp->graph&&lp->graph!=g&&(!lp->graph->end||lp->graph->end->code!=BRA)) i=1;
  458.                     for(lp=b->in;lp;lp=lp->next)
  459.                         if(lp->graph&&lp->graph!=g&&(!lp->graph->end||lp->graph->end->code!=BRA)) i=1;
  460.                     if(!i){
  461.                         if(!(tp=g->end->prev)) ierror(0);
  462.                         if(tp->code!=TEST&&tp->code!=COMPARE)
  463.                             ierror(0);
  464.                         /*  schauen, ob die Anweisung eine evtl. TEST   */
  465.                         /*  oder COMPARE-Anweisung beeinflusst          */
  466.                         destroys=0;
  467.                         if(as->z.flags&DREFOBJ) destroys|=1;
  468.                         if(as->code==CALL) destroys|=2;
  469.                         if(tp->q1.flags&VAR){
  470.                             if(destroys&3){
  471.                                 if((tp->q1.v->flags&USEDASADR)||
  472.                                    (tp->q1.flags&DREFOBJ)||
  473.                                    (tp->q1.v->storage_class==EXTERN)||
  474.                                    (tp->q1.v->nesting==0))
  475.                                     i=1;
  476.                                 if((destroys&2)&&tp->q1.v->storage_class==STATIC)
  477.                                     i=1;
  478.                             }
  479.                             if((as->z.flags&VAR)&&as->z.v==tp->q1.v)
  480.                                     i=1;
  481.                         }
  482.                         if(tp->q2.flags&VAR){
  483.                             if(destroys&3){
  484.                                 if((tp->q2.v->flags&USEDASADR)||
  485.                                    (tp->q2.flags&DREFOBJ)||
  486.                                    (tp->q2.v->storage_class==EXTERN)||
  487.                                    (tp->q2.v->nesting==0))
  488.                                     i=1;
  489.                                 if((destroys&2)&&tp->q2.v->storage_class==STATIC)
  490.                                     i=1;
  491.                             }
  492.                             if((as->z.flags&VAR)&&as->z.v==tp->q2.v)
  493.                                 i=1;
  494.                         }
  495.                         if(!i){
  496.                             if(DEBUG&1024){ printf("moving instruction from following blocks to predecessor:\n");pric2(stdout,as);}
  497.                             p=mymalloc(ICS);
  498.                             memcpy(p,as,ICS);
  499.                             remove_IC_fg(a,as);
  500.                             remove_IC_fg(b,bs);
  501.                             p->use_cnt=p->change_cnt=0;
  502.                             p->use_list=p->change_list=0;
  503.                             insert_IC_fg(g,g->end->prev->prev,p);
  504.                             changed=gchanged=1;
  505.                         }
  506.                     }
  507.                 }
  508.             }
  509.             g=g->normalout;
  510.         }
  511.         if(changed) free_flowgraph(fg);
  512.     }while(changed);
  513.     return(fg);
  514. }
  515.  
  516. void insert_IC_fg(struct flowgraph *fg,struct IC *p,struct IC *new)
  517. /*  fuegt ein IC hinter p ein unter Beibehaltung des Flussgraphen   */
  518. {
  519.     if(fg->start){
  520.         if(!p||p==fg->start->prev) fg->start=new;
  521.         if(p==fg->end) fg->end=new;
  522.     }else{
  523.         fg->start=fg->end=new;
  524.     }
  525.     insert_IC(p,new);
  526. }
  527.